package Main.tcp;

import Main.pojo.TcpMessage;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.LocalDateTime;

/**
 * PACKAGE_NAME: Main.tcp
 * Description:
 * 测试端口复用
 */
public class TCPTest2 {
    public static void main(String[] args) throws InterruptedException, IOException, ClassNotFoundException {
        // 创建ServerSocket
        new Thread(new Runnable() {
            @Override
            public void run() {
                ServerSocket serverSocket = null;
                try {
                    serverSocket = new ServerSocket();
                    serverSocket.setReuseAddress(true);
                    serverSocket.bind(new InetSocketAddress(19999));
                    while (true) {
                        Socket socket = serverSocket.accept();
                        String ip = socket.getInetAddress().getHostAddress();
                        int port = socket.getPort();
                        TcpMessage tcpMessage = new TcpMessage();
                        tcpMessage.code = port;
                        tcpMessage.msg = ip;
                        ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
                        out.writeObject(tcpMessage);
                        out.close();
                        socket.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        Thread.sleep(1000);
        System.out.println("第一次连接");
        Socket socket = new Socket("localhost", 19999);
        System.out.println("使用newSocket，随机的本地端口是：" + socket.getLocalPort());
        ObjectInputStream objIn = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
        TcpMessage tcpMessage = (TcpMessage) objIn.readObject();
        System.out.println("收到的信息[" + LocalDateTime.now() + "]：" +
                tcpMessage);
        int port = tcpMessage.code;
        String ip = tcpMessage.msg;
        objIn.close();
        socket.close();
        System.out.println("开始端口复用！");
        for (int i = 0; i < 5; i++) {
            Socket newSocket = new Socket();
            System.out.println("I:" + i);
            newSocket.setReuseAddress(true);
            newSocket.bind(new InetSocketAddress(ip, port));
            newSocket.connect(new InetSocketAddress("localhost", 19999));
            ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(newSocket.getInputStream()));
            TcpMessage tcpMessage1 = (TcpMessage) in.readObject();
            System.out.println("收到的信息[" + LocalDateTime.now() + "]：" +
                    tcpMessage1);
            in.close();
            newSocket.close();
        }
        // 测试，如果socket 绑定成功了本地IP与PORT，但是没有连接成功对方，那么我还能用该信息创建Server服务不？
        Socket testSocket = new Socket();
        System.out.println("测试，如果socket 绑定成功了本地IP与PORT，但是没有连接成功对方，那么我还能用该信息创建Server服务不？" );
        testSocket.setReuseAddress(true);
        testSocket.bind(new InetSocketAddress(ip, port));
        // 一定连接失败
        try {
            testSocket.connect(new InetSocketAddress("ojbk.net", 19999), 140);
            // 如果失败，这个socket就会直接挂关闭
        } catch (IOException e) {
            System.out.println("成功：连接失败！");
        }
        // 答案： 可以！！！！！！！！因为连接失败了就会直接关闭
        // 监听服务试试
        // 测试，如果连接成功？不关闭连接呢？
        //Socket testSocket1 = new Socket();
        //testSocket1.setReuseAddress(true);
        //testSocket1.bind(new InetSocketAddress(ip, port));
        //testSocket1.connect(new InetSocketAddress("localhost", 19999));
        // 答案:不可以噢！！
        // 测试：如果绑定了，但是没有connect，那么此端口可以被其他用嘛?目测不可以
        //Socket testSocket1 = new Socket();
        //testSocket1.setReuseAddress(true);
        //testSocket1.bind(new InetSocketAddress(ip, port));
        // 答案：java.net.BindException: Address already in use: JVM_Bind

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("用原端口创建服务!");
                try {
                    ServerSocket serverSocket = new ServerSocket(port);
                    Socket socket1 = serverSocket.accept();
                    System.out.println("创建成功！");
                    socket1.getOutputStream().write("成功！".getBytes());
                    socket1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        Thread.sleep(500);
        System.out.println("开始连接，Server!");
        Socket tSocket1 = new Socket("localhost", port);
        Byte[] data = new Byte[100];
        int a = tSocket1.getInputStream().read();
        System.out.println(a);
    }
}
